﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SeaBattle.UI.Web.Models;
using SeaBattle.Domain.Abstract.Services;
using SeaBattle.Domain.Abstract;
using SeaBattle.Domain.Entities;
using System.IO;

namespace SeaBattle.UI.Web.Controllers
{
    [Authorize]
    public class GameController : Controller
    {
        private IGameService gameService;
        private IPlayerService playerService;
        private IGameRepository gameRepository;
        private IAccountService accountService;

        public GameController(IGameService gameService, IPlayerService playerService, IGameRepository gameRepository, IAccountService accountService)
        {
            this.gameRepository = gameRepository;
            this.gameService = gameService;
            this.playerService = playerService;
            this.accountService = accountService;
        }
        //
        // GET: /Game/

        public ActionResult Index(int id = -1)
        {
            if (id == -1)
                return RedirectToAction("Index", "Room");
            // Get Game
            var game = gameRepository.GetGame(id);
            var me = playerService.GetPlayer(User.Identity.Name);
            Session["SetGame"] = game;
            if (game.Opponent == null)
            {
                game.JoinOpponent(me);
                var myBalance = accountService.GetPlayerBalance(me);
                accountService.SetPlayerBalance(me, myBalance - game.Preset);
            }
            if (game.isEnd)
                return RedirectToAction("GameResult");
            if (game.State == GameState.STATE_PLAY)
                return RedirectToAction("GamePlay");
            return RedirectToAction("BoardSetup");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ActionResult ResetField()
        {
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            var user = playerService.GetPlayer(User.Identity.Name);
            game.ResetField(user);

            return RedirectToAction("BoardSetup");
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ActionResult CheckStart()
        {
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            var user = playerService.GetPlayer(User.Identity.Name);
            var opponent = user == game.Creator ? game.Opponent : game.Creator;
            if (game.BoardStates[user] != BoardSetupState.STATEEND)
                return RedirectToAction("BoardSetup");
            else if (game.BoardStates[opponent] == BoardSetupState.STATEEND)
            {
                if (game.State != GameState.STATE_PLAY)
                    game.Start();
                return RedirectToAction("GamePlay");
            }
            return RedirectToAction("BoardSetup");   
        }

        public ActionResult GameResult()
        {
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            if (game.isEnd == false)
                return RedirectToAction("Index", "Room");
            Player winner = game.Winner;
            Player loser = winner == game.Creator ? game.Opponent : game.Creator;
            if (!game.ChangePreset)
            {
                var myBalance = accountService.GetPlayerBalance(winner);
                accountService.SetPlayerBalance(winner, myBalance + 2*game.Preset);
            }
            {//DEMO
                using (StreamWriter stream = new StreamWriter(@"\Fields.txt"))
                {
                    var field = game.realField[winner];
                        for (int i = 0; i < field.Size; i++)
                        {
                            for (int j = 0; j < field.Size; j++)
                            {
                                stream.Write(((int)field.AField[i, j]).ToString() + "\t");
                            }
                            stream.WriteLine();
                        }

                    field = game.realField[loser];
                        for (int i = 0; i < field.Size; i++)
                        {
                            for (int j = 0; j < field.Size; j++)
                            {
                                stream.Write(((int)field.AField[i, j]).ToString() + "\t");
                            }
                            stream.WriteLine();
                        }
                }
            }
            return View(new GameResultModel { Game = game, Winner = winner, Loser = loser });
        }

        public ActionResult GamePlay()
        {
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            if (game.isEnd)
                return RedirectToAction("GameResult");
            var user = playerService.GetPlayer(User.Identity.Name);
            return View(new GamePlayModel { Game = game, User = user });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ActionResult BoardSetup()
        {
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            var user = playerService.GetPlayer(User.Identity.Name);
            return View(new GameBoardSetupModel { Game = game, User = user });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public ActionResult BoardSetting(string index="")
        {
            if (index == null || index == "")
                return RedirectToAction("Index", "Romm");
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            var user = playerService.GetPlayer(User.Identity.Name);
            var Index = int.Parse(index);
            int i = Index / 10;
            int j = i == 0 ? Index : Index % (i * 10);            
            game.Setting(user, i, j);
            return RedirectToAction("BoardSetup");
        }

        public ActionResult Shot(string index = "")
        {
            if (index == null || index == "")
                return RedirectToAction("Index", "Romm");
            if (Session["SetGame"] == null)
                return RedirectToAction("Index", "Room");
            var game = (Game)Session["SetGame"];
            var user = playerService.GetPlayer(User.Identity.Name);
            var Index = int.Parse(index);
            int i = Index / 10;
            int j = i == 0 ? Index : Index % (i * 10);
            var isEnd = game.Shot(user, i, j);
            return RedirectToAction("GamePlay");
        }
    }
}
